package com.yonyou.service;

import com.yonyou.dao.entity.*;
import com.yonyou.dao.mapper.IBOMapper;
import com.yonyou.dao.mapper.ITemplateItemMapper;
import com.yonyou.dao.mapper.ITemplateMapper;
import com.yonyou.print.params.ParamsEngine;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by yijx on 2018/1/2.
 */

@Service("printDBService")
public class PrintDBService {

    @Autowired
    private IBOMapper iboMapper;
    @Autowired
    private ITemplateMapper iTemplateMapper;
    @Autowired
    private ITemplateItemMapper iTemplateItemMapper;

    /**
     * 简单测试数据库是否能连接
     * @return
     */
    public boolean connectDB(){
        String url = "jdbc:mysql://"+ParamsEngine.getInfoConfig().getProperty("jdbc.mysql.url")+"/"+
                ParamsEngine.getInfoConfig().getProperty("jdbc.mysql.name")+"?useUnicode=true&amp;characterEncoding=utf8";
        return testConnection(url,ParamsEngine.getInfoConfig().getProperty("jdbc.mysql.username"),
                ParamsEngine.getInfoConfig().getProperty("jdbc.mysql.password"));
    }

    /**
     * 测试数据库(dbName)是否能连接，如果不能，测试数据库ip端口是否正确,如果正确，创建数据库(dbName)
     * @param address   数据库地址(ip+port)
     * @param dbName    数据库名称
     * @param user      数据库用户名
     * @param password  密码
     * @return          -1(连接失败),1(连接成功),2(创建数据库dbName)
     */
    public int connectDB(String address,String dbName,String user,String password){
        String url = "jdbc:mysql://"+address+"/"+dbName+"?useUnicode=true&amp;characterEncoding=utf8";
        if(testConnection(url,user,password)){
            return 1;
        }else{
            String noNameUrl = "jdbc:mysql://"+address+"/"+"?useUnicode=true&amp;characterEncoding=utf8";
            if(testConnection(noNameUrl,user,password)){
                int createResult = createDB(noNameUrl,dbName,user,password);
                if(createResult>0){
                    if(testConnection(url,user,password)){
                        return 2;
                    }
                }
            }
        }
        return -1;
    }

    /**
     * jdbc测试数据库是否能连接
     * @param url
     * @param user
     * @param password
     * @return
     */
    private boolean testConnection(String url,String user,String password){
        try{
            Class.forName(ParamsEngine.getInfoConfig().getProperty("jdbc.mysql.driver"));//创建驱动器
            Connection con = DriverManager.getConnection(url,user,password);
            con.close();
            return true;
        }catch (ClassNotFoundException exception){
            return false;
        }catch (SQLException exception){
            return false;
        }
    }

    /**
     * jdbc创建数据库
     */
    public int createDB(String url,String dbName,String dbUser,String password){
        try{
            Class.forName(ParamsEngine.getInfoConfig().getProperty("jdbc.mysql.driver"));//创建驱动器
            Connection con = DriverManager.getConnection(url,dbUser,password);
            String createDB ="CREATE DATABASE IF NOT EXISTS "+dbName;
            Statement stat = con.createStatement();
            int result =stat.executeUpdate(createDB);
            stat.close();
            con.close();
            return result;
        }catch (ClassNotFoundException exception){
            return -1;
        }catch (SQLException exception){
            return -1;
        }
    }

    /**
     * 初始化建表
     */
    public void init() {
        iboMapper.createTable("print_bo");
        iTemplateMapper.createTable("print_template");
        iTemplateItemMapper.createTable("print_template_item");
    }

    /**
     * 同步云打印模板到本地
     *
     * @param bos         云端BO
     * @param templateVOS 云端模板
     * @return 新增、修改的模板的编码，用于同步模板属性
     */
    public List<String> syncAllTemplates(List<BOVO> bos, List<TemplateVO> templateVOS) {
        //1、查询数据库BO和模板
        List<BOVO> originalBOs = iboMapper.getAllBO();
        List<TemplateJoinBOViewVO> originalTemplates = iTemplateMapper.getAllTemplates();
        //2、对比
        List<BOVO> updateBOs = new ArrayList<BOVO>();
        List<BOVO> addBOs = new ArrayList<BOVO>();
        List<TemplateVO> updateTemplates = new ArrayList<TemplateVO>();
        List<TemplateVO> addTemplates = new ArrayList<TemplateVO>();
        //对比BO
        Map<String, BOVO> boPKMap = new HashMap<String, BOVO>();
        for (int i = 0; i < originalBOs.size(); i++) {
            BOVO originalBO = originalBOs.get(i);
            boPKMap.put(originalBO.getPk_bo(), originalBO);
        }
        for (int i = 0; i < bos.size(); i++) {
            BOVO bo = bos.get(i);
            if (boPKMap.containsKey(bo.getPk_bo())) {
                BOVO originalBO = boPKMap.get(bo.getPk_bo());
                //如果bo在本地数据库中已存在，进行对比
                if (!originalBO.getBo_name().equals(bo.getBo_name()) ||
                        !originalBO.isIspublished() == bo.isIspublished() ||
                        !originalBO.isIspublishedrefer() == bo.isIspublishedrefer()) {
                    updateBOs.add(bo);
                }
                //删除已对比过的，剩下的是云端已删除的
                boPKMap.remove(bo.getPk_bo());
            } else {
                addBOs.add(bo);
            }
        }
        //对比模板Template
        Map<String, TemplateJoinBOViewVO> templatePKMap = new HashMap<String, TemplateJoinBOViewVO>();
        List<String> changeTemplateCodes = new ArrayList<String>();
        for (int i = 0; i < originalTemplates.size(); i++) {
            TemplateJoinBOViewVO originalTemplate = originalTemplates.get(i);
            templatePKMap.put(originalTemplate.getPk_print_template(), originalTemplate);
        }
        for (int i = 0; i < templateVOS.size(); i++) {
            TemplateVO templateVO = templateVOS.get(i);
            if (templatePKMap.containsKey(templateVO.getPk_print_template())) {
                //如果模板在本地数据库中已存在，对比version，本地version更小则更新
                if (templatePKMap.get(templateVO.getPk_print_template()).getVersionid() < templateVO.getVersionid()) {
                    updateTemplates.add(templateVO);
                    changeTemplateCodes.add(templateVO.getTemplatecode());
                }
                //删除已对比过的，剩下的是云端已删除的
                templatePKMap.remove(templateVO.getPk_print_template());
            } else {
                addTemplates.add(templateVO);
                changeTemplateCodes.add(templateVO.getTemplatecode());
            }
        }
        //3、分别处理模板新增、修改、删除
        //bo新增、修改、删除
        if (addBOs.size() > 0) {
            iboMapper.add("print_bo", addBOs);
        }
        for (int i = 0; i < updateBOs.size(); i++) {
            iboMapper.updateBO(updateBOs.get(i));
        }
        if (boPKMap.keySet().size() > 0) {
            List<String> deleteList = new ArrayList<String>();
            deleteList.addAll(boPKMap.keySet());
            iboMapper.deleteByPKs(deleteList);
        }

        //模板新增、修改、删除
        if (addTemplates.size() > 0) {
            iTemplateMapper.add("print_template", addTemplates);
        }
        for (int i = 0; i < updateTemplates.size(); i++) {
            iTemplateMapper.updateTemplate(updateTemplates.get(i));
        }
        if (templatePKMap.keySet().size() > 0) {
            List<String> deleteList = new ArrayList<String>();
            deleteList.addAll(templatePKMap.keySet());
            iTemplateMapper.deleteByPKs(deleteList);
        }

        //返回新增、修改的模板的编码，用于同步模板属性
        return changeTemplateCodes;
    }

    /**
     * 批量保存BO
     *
     * @param bos
     * @return
     */
    public int saveBO(List<BOVO> bos) {
        return iboMapper.add("print_bo", bos);
    }

    /**
     * 用bo_code查询BO
     * @param bo_code
     * @return
     */
    public List<BOVO> findBO(String bo_code){
        return iboMapper.findBOByCode(bo_code);
    }
    /**
     * 批量保存模板信息
     *
     * @param VOs
     * @return
     */
    public int saveTemplates(List<TemplateVO> VOs) {
        return iTemplateMapper.add("print_template", VOs);
    }

    /**
     * 本地数据库删除模板
     *
     * @param pk_print_template 模板pk
     * @return
     */
    public int deleteTemplate(String pk_print_template) {
        List<String> deleteList = new ArrayList<String>();
        deleteList.add(pk_print_template);
        return iTemplateMapper.deleteByPKs(deleteList);
    }

    /**
     * 保存打印模型
     *
     * @param templateModelVO
     * @return
     */
    public int saveTemplateItems(List<TemplateModelVO> templateModelVO) {
        int resultNum = 0;
        //分别取模板和模板item数据
        List<TemplateItemVO> templateItemVOS = new ArrayList<TemplateItemVO>();
        List<String> deleteTemplates = new ArrayList<String>();
        for (int i = 0; i < templateModelVO.size(); i++) {
            deleteTemplates.add(templateModelVO.get(i).getPk_print_template());
        }
        iTemplateItemMapper.deleteByPKs(deleteTemplates);
        for (int i = 0; i < templateModelVO.size(); i++) {
            TemplateModelVO modelVO = templateModelVO.get(i);
            //更新print_template模板表 模板宽高
            iTemplateMapper.updateTemplatePage(modelVO.getPk_print_template(), modelVO.getPageHeight(),
                    modelVO.getPageWidth(), modelVO.getVersion());
            for (int j = 0; j < modelVO.getModels().size(); j++) {
                templateItemVOS.addAll(templateModelVO.get(i).getModels());
            }
            //mysql sql语句长度上限为4M,保守估计限制每次批量插入略大于400条
            if (templateItemVOS.size() > 400) {
                resultNum += iTemplateItemMapper.add("print_template_item", templateItemVOS);
                templateItemVOS.clear();
            }
        }
        if (templateItemVOS.size() > 0) {
            resultNum += iTemplateItemMapper.add("print_template_item", templateItemVOS);
        }
        //模板item保存到数据库
        return resultNum;

    }

    /**
     * 用模板编码查询打印模板模型
     *
     * @param templateCode
     * @return
     */
    public TemplateModelVO getTemplateModel(@Param("templateCode") String templateCode) {
        TemplateModelVO templateModelVO = iTemplateMapper.getTemplateModel(templateCode);
        return templateModelVO;
    }

    /**
     * 查询打印模板信息
     *
     * @param bo_code
     * @return
     */
    public List<TemplateJoinBOViewVO> getAllTemplates(@Param("bo_code") String bo_code) {
        List<TemplateJoinBOViewVO> templateJoinBOViewVOS = null;
        if (bo_code == null || bo_code.equals("")) {
            //bo_cod空，查询本地所有模板
            templateJoinBOViewVOS = iTemplateMapper.getAllTemplates();
        } else {
            //查询该bo_code 的所有模板
            templateJoinBOViewVOS = iTemplateMapper.getTemplatesByBO(bo_code);
        }
        return templateJoinBOViewVOS;
    }
}
